<?php

namespace addons\member\utils;

use addons\member\model\MemberAccountModel;
use addons\member\model\MemberPool;
use addons\member\model\PhysicalContribution;
use addons\member\model\Balance;
use addons\member\model\TradingRecord;
use addons\member\model\LevelConfig;
use addons\member\model\VipLevel;
use web\common\model\sys\SysParameterModel;
use addons\shop\model\ShopOrder;
use addons\config\model\Area;
use addons\shop\model\Store;
use addons\equip\model\Equip;
use addons\equip\model\EquipOrder;
use addons\shop\model\StoreSubsidy;
/**
 * 奖励设置
 */
class Reward{

    protected $userM;
    protected $poolM;
    protected $phyM;
    protected $balanceM;
    protected $recordM;
    protected $sysM;
    protected $areaM;
    protected $storeM;
    protected $equipM;
    protected $shopOrderM;
    protected $equipOrderM;
    protected $storeSubsidyM;
    protected $levelConfigM;
    protected $vipLevelM;



    public function __construct(){
        $this->userM = new MemberAccountModel;
        $this->phyM = new PhysicalContribution;
        $this->balanceM = new Balance;
        $this->recordM = new TradingRecord;
        $this->sysM = new SysParameterModel;
        $this->equipM = new Equip;
        $this->shopOrderM = new ShopOrder;
        $this->equipOrderM = new EquipOrder;
        $this->levelConfigM = new LevelConfig;
        $this->vipLevelM = new VipLevel;
    }
    
    /**
     * 用户升级
     */
    public function userUpdate($user_id){
        // echo "in userUpdate\n";
        $pid_path = $this->userM->where('id',$user_id)->value('pid_path');
        $list = $this->equipOrderM->field('user_id')->where(['user_id'=>['in',$pid_path.','.$user_id],'status'=>0])->order('user_id desc')->select();
        $vip_data = $this->levelConfigM->where('level>0')->order('level desc')->select();
        // $vip_data = $this->levelConfigM->where(['level'=>['>',0]])->order('level desc')->select();
        foreach ($list as $k => $v) {
            $this->updateUserLevel($v['user_id'],$vip_data);
        }
    }

    /**
     * 用户VIP升级
     */
    public function VipuserUpdate($user_id){
        // echo "in VipuserUpdate\n";
        $pid_path = ($this->userM->where('id',$user_id)->value('pid_path')).','.$user_id;
        $list = array_filter(explode(',', $pid_path));
        // $list = $this->equipOrderM->field('user_id')->where(['user_id'=>['in',$pid_path],'status'=>0])->order('user_id desc')->select();
        $vip_data = $this->vipLevelM->where('level>0')->order('level desc')->select();
        // $vip_data = $this->levelConfigM->where(['level'=>['>',0]])->order('level desc')->select();
        foreach ($list as $k => $v) {
            $this->updateVipUserLevel($v,$vip_data);
        }
    }
    

    public function allLevelup(){
        $level_data = $this->levelConfigM->where('level>0')->order('level desc')->select();
        $vip_data = $this->vipLevelM->where('level>0')->order('level desc')->select();
        $field = 'id';
        $map = [];
        $page = 0;
        $rows = 100;
        $list = $this->userM->field($field)->where($map)->limit($page*$rows,$rows)->select(); 
        while ($list) {
            foreach ($list as $k => $v) {
                // $this->userM->where('id',$v['id'])->update(['level'=>0,'update_time'=>NOW_DATETIME]);
                $this->updateUserLevel($v['id'],$level_data);
                $this->updateVipUserLevel($v['id'],$vip_data);
            }
            $page++;
            echo "page:{$page}\n";
            $list = $this->userM->field($field)->where($map)->limit($page*$rows,$rows)->select(); 
        }
    }
    /**
     * 分享奖
     */
    public function shareReward($user_id,$amount,$cny_amount,$rate){
        echo "in shareReward\n";
        if(!$user_id&&!$amount) return false;
        // $profit = $this->sysM->getValByName('first_push');
        $first_push = $this->sysM->getValByName('first_push');
        $pid = $this->userM->where('id',$user_id)->value('pid');
        $ex1 = $this->equipOrderM->where('user_id',$pid)->value('id');
        $release_amount = bcmul($first_push/100, $amount,2);
        if($ex1){
            $this->updateAmountRecord($pid,$release_amount,1,16,'直推奖励',$user_id);
        }
        // $ppid = $this->userM->where('id',$pid)->value('pid');
        // $ex2 = $this->equipOrderM->where('user_id',$ppid)->value('id');
        // if($ex2){
        //     $this->updateAmountRecord($ppid,$profit['second_push'],3,16,'次推推奖励',$user_id);
        // }
        return true;
    }



    /**
     * 静态分享
     */
    public function staticShare($user_id,$amount,$cny_amount,$rate){
        if(!$user_id&&!$amount) return false;
        $static_share = $this->sysM->getValByName('static_share');
        $pid_path = $this->userM->where('id',$user_id)->value('pid_path');
        $data = $this->poolM->field('user_id')->where(['user_id'=>['in',$pid_path],'gratitude_pool'=>['>',0]])->order('user_id desc')->find();
        if($data){
            $release_amount = bcmul($amount, $static_share/100,4);
            $this->addAmountRecord($data['user_id'],$cny_amount,$release_amount,$rate,2,16,'静态分享收益',$user_id);
        }
        return true;
    }

    public function test($user_id){
        $count = 0;
        $push_list = $this->userM->where('pid',$user_id)->field('id,level')->select();
        foreach ($push_list as $key => $val) {
            if($val['level']>=1){
                // echo "user_id:{$val['id']}\n";
                $count++;
            }else{
                $c = $this->userM->alias('u')->join($this->equipOrderM->getTable().' p','u.id=p.user_id')->field('u.id')->where(['pid_path'=>['like','%,'.$val['id'].',%'],'status'=>0,'level'=>['>=',1]])->group('user_id')->count();
                if($c>0){
                    $count++;
                }
            }
            if($count>=3){
                $is_up=1;
                break;                    
            }
        }
    }


    /**
     * 更新会员等级
     */
    public function updateUserLevel($user_id,$vip_data){
        if($user_id<=0) return false;
        $ex = $this->equipOrderM->where('user_id',$user_id)->value('id');
        if(!$ex) return false;
        $user_data = $this->userM->getDetail($user_id,'level,vip_level');
        $push_count = $this->userM->alias('u')->join($this->equipOrderM->getTable().' p','u.id=p.user_id')->field('u.id')->where(['pid'=>$user_id])->group('user_id')->count();
        $act_info = $this->phyM->where('user_id',$user_id)->find();
        $small_list = $this->userM->alias('u')->join($this->phyM->getTable().' p','u.id=p.user_id')->field('p.user_id,(activity+single_activity) small')->where(['pid'=>$user_id])->order('small desc')->limit(0,2)->select();
        $small = $act_info['activity'];
        foreach ($small_list as $key => $value) {
            $small = $small-$value['small'];
        }
        $is_up = 0;
        $is_down = 1;
        $count = 0;
        $push_list = $this->userM->where('pid',$user_id)->field('id,level')->select();
        // echo "user_id:{$user_id}|small:{$small}|\n";
        if($user_data['level']==0){
            $is_up = 1;
        }elseif($user_data['level']==1){
            foreach ($push_list as $key => $val) {
                if($val['level']>=1){
                    $count++;
                }else{
                    $c = $this->userM->alias('u')->join($this->equipOrderM->getTable().' p','u.id=p.user_id')->field('u.id')->where(['pid_path'=>['like','%,'.$val['id'].',%'],'status'=>0,'level'=>['>=',1]])->group('user_id')->count();
                    if($c>0){
                        $count++;
                    }
                }
                if($count>=3){
                    $is_up=1;
                    break;                    
                }
            }
            $is_down = 0;
        }elseif($user_data['level']==2){
            $count1 = 0;
            foreach ($push_list as $key => $val) {
                if($val['level']==1){
                    $count1++;
                }elseif($val['level']>1){
                    $count++;
                }else{
                    if($count1<1){
                        $c1 = $this->userM->alias('u')->join($this->equipOrderM->getTable().' p','u.id=p.user_id')->field('u.id')->where(['pid_path'=>['like','%,'.$val['id'].',%'],'status'=>0,'level'=>['=',1]])->group('user_id')->count();
                        $c = $this->userM->alias('u')->join($this->equipOrderM->getTable().' p','u.id=p.user_id')->field('u.id')->where(['pid_path'=>['like','%,'.$val['id'].',%'],'status'=>0,'level'=>['>',1]])->group('user_id')->count();
                        if($c1>0){
                            $count1++;
                        }
                        if($c>0){
                            $count++;
                        }
                    }else{
                        $c = $this->userM->alias('u')->join($this->equipOrderM->getTable().' p','u.id=p.user_id')->field('u.id')->where(['pid_path'=>['like','%,'.$val['id'].',%'],'status'=>0,'level'=>['>',1]])->group('user_id')->count();
                        if($c>0){
                            $count++;
                        }
                    }
                }
                if($count>=3||($count>=2&&$count1>=1)){
                    $is_up=1;
                    break;
                }
            }
            $count = 0;
            foreach ($push_list as $key => $val) {
                if($val['level']>=1){
                    $count++;
                }else{
                    $c = $this->userM->alias('u')->join($this->equipOrderM->getTable().' p','u.id=p.user_id')->field('u.id')->where(['pid_path'=>['like','%,'.$val['id'].',%'],'status'=>0,'level'=>['>=',1]])->group('user_id')->count();
                    if($c>0){
                        $count++;
                    }
                }
                if($count>=3){
                    $is_down=0;
                    break;
                }
            }
        }elseif($user_data['level']==3){
            $count1 = 0;
            foreach ($push_list as $key => $val) {
                if($val['level']==1||$val['level']==2){
                    $count1++;
                }elseif($val['level']>2){
                    $count++;
                }else{
                    if($count1<1){
                        $c1 = $this->userM->alias('u')->join($this->equipOrderM->getTable().' p','u.id=p.user_id')->field('u.id')->where(['pid_path'=>['like','%,'.$val['id'].',%'],'status'=>0,'level'=>['=',1]])->group('user_id')->count();
                        $c2 = $this->userM->alias('u')->join($this->equipOrderM->getTable().' p','u.id=p.user_id')->field('u.id')->where(['pid_path'=>['like','%,'.$val['id'].',%'],'status'=>0,'level'=>['=',2]])->group('user_id')->count();
                        $c = $this->userM->alias('u')->join($this->equipOrderM->getTable().' p','u.id=p.user_id')->field('u.id')->where(['pid_path'=>['like','%,'.$val['id'].',%'],'status'=>0,'level'=>['>',2]])->group('user_id')->count();
                        if($c1>0||$c2>0){
                            $count1++;
                        }
                        if($c>0){
                            $count++;
                        }
                    }else{
                        $c = $this->userM->alias('u')->join($this->equipOrderM->getTable().' p','u.id=p.user_id')->field('u.id')->where(['pid_path'=>['like','%,'.$val['id'].',%'],'status'=>0,'level'=>['>',2]])->group('user_id')->count();
                        if($c>0){
                            $count++;
                        }
                    }
                }
                // echo "user_id:{$val['id']}|count:{$count}|count1:{$count1}\n";
                if($count>=3||($count>=2&&$count1>=1)){
                    $is_up=1;
                    break;
                }
            }
            $count = 0;
            $count1 = 0;
            foreach ($push_list as $key => $val) {
                if($val['level']==1){
                    $count1++;
                }elseif($val['level']>1){
                    $count++;
                }else{
                    if($count1<1){
                        $c1 = $this->userM->alias('u')->join($this->equipOrderM->getTable().' p','u.id=p.user_id')->field('u.id')->where(['pid_path'=>['like','%,'.$val['id'].',%'],'status'=>0,'level'=>['=',1]])->group('user_id')->count();
                        $c = $this->userM->alias('u')->join($this->equipOrderM->getTable().' p','u.id=p.user_id')->field('u.id')->where(['pid_path'=>['like','%,'.$val['id'].',%'],'status'=>0,'level'=>['>',1]])->group('user_id')->count();
                        if($c1>0){
                            $count1++;
                        }
                        if($c>0){
                            $count++;
                        }
                    }else{
                        $c = $this->userM->alias('u')->join($this->equipOrderM->getTable().' p','u.id=p.user_id')->field('u.id')->where(['pid_path'=>['like','%,'.$val['id'].',%'],'status'=>0,'level'=>['>',1]])->group('user_id')->count();
                        if($c>0){
                            $count++;
                        }
                    }
                }
                if($count>=3||($count>=2&&$count1>=1)){
                    $is_down=0;
                    break;
                }
            }
        }elseif($user_data['level']==4){
            $count1 = 0;
            foreach ($push_list as $key => $val) {
                if($val['level']==1||$val['level']==2){
                    $count1++;
                }elseif($val['level']>2){
                    $count++;
                }else{
                    if($count1<1){
                        $c1 = $this->userM->alias('u')->join($this->equipOrderM->getTable().' p','u.id=p.user_id')->field('u.id')->where(['pid_path'=>['like','%,'.$val['id'].',%'],'status'=>0,'level'=>['=',1]])->group('user_id')->count();
                        $c2 = $this->userM->alias('u')->join($this->equipOrderM->getTable().' p','u.id=p.user_id')->field('u.id')->where(['pid_path'=>['like','%,'.$val['id'].',%'],'status'=>0,'level'=>['=',2]])->group('user_id')->count();
                        $c = $this->userM->alias('u')->join($this->equipOrderM->getTable().' p','u.id=p.user_id')->field('u.id')->where(['pid_path'=>['like','%,'.$val['id'].',%'],'status'=>0,'level'=>['>',2]])->group('user_id')->count();
                        if($c1>0||$c2>0){
                            $count1++;
                        }
                        if($c>0){
                            $count++;
                        }
                    }else{
                        $c = $this->userM->alias('u')->join($this->equipOrderM->getTable().' p','u.id=p.user_id')->field('u.id')->where(['pid_path'=>['like','%,'.$val['id'].',%'],'status'=>0,'level'=>['>',2]])->group('user_id')->count();
                        if($c>0){
                            $count++;
                        }
                    }
                }
                if($count>=3||($count>=2&&$count1>=1)){
                    $is_down=0;
                    break;
                }
            }
        }
        // echo "user_id:{$user_id}|level:{$user_data['level']}|push_count:{$push_count}|big:{$act_info['activity']}|small:{$small}|is_ip:{$is_up}|is_done:{$is_down}\n";
        foreach ($vip_data as $k => $v) {
            if($v['level']==0){
                if($push_count>=$v['need_push']&&$act_info['activity']>=$v['need_contribution']&&$small>=$v['amount']){
                    //升级
                    if($v['level']>$user_data['level']){
                        return $this->userM->where('id',$user_id)->update(['level'=>$v['level']]);
                    }
                }
            }else{
                //降级
                if($v['level']==$user_data['level']){
                    if(!($is_up==1&&$push_count>=$v['need_push']&&$act_info['activity']>=$v['need_contribution']&&$small>=$v['amount'])){
                        if($is_down==1) return $this->userM->where('id',$user_id)->update(['level'=>($v['level']-1)]);
                    }
                }
                if($is_up==1&&$push_count>=$v['need_push']&&$act_info['activity']>=$v['need_contribution']&&$small>=$v['amount']){
                    //升级
                    if($v['level']>$user_data['level']){
                        // $ex_id = $this->equipOrderM->where(['user_id'=>$user_id,'e_id'=>$v['send_equip'],'is_send'=>1,'send_type'=>1])->value('id');
                        // if(!$ex_id){
                        //     $eqip_data = $this->equipM->getDetail($v['send_equip']);
                        //     $eqip_data['user_id'] = $user_id;
                        //     $res = $this->equipOrderM->createEquip($eqip_data,1,1);
                        // }
                        return $this->userM->where('id',$user_id)->update(['level'=>$v['level']]);
                    }
                }
            }
        }

    }


    /**
     * 更新会员等级
     */
    public function updateVipUserLevel($user_id,$vip_data){
        // echo "updateVipUserLevel \n";
        if($user_id<=0) return false;
        $ex = $this->equipOrderM->where('user_id',$user_id)->value('id');
        if(!$ex) return false;
        $user_data = $this->userM->getDetail($user_id,'level,vip_level');
        $push_count = $this->userM->alias('u')->join($this->equipOrderM->getTable().' p','u.id=p.user_id')->field('u.id')->where(['pid'=>$user_id])->group('user_id')->count();
        // echo "user_id:{$user_id}|vip_level:{$user_data['vip_level']}|push_count:{$push_count}|\n";
        foreach ($vip_data as $k => $v) {
            if($v['level']==$user_data['vip_level']){
                if($v['need_push']>$push_count){
                    return $this->userM->where('id',$user_id)->update(['vip_level'=>$v['level']-1,'with_rate'=>$v['rate']]);
                }
            }
            if($v['need_push']<=$push_count){
                //升级
                if($v['level']>$user_data['vip_level']){
                    return $this->userM->where('id',$user_id)->update(['vip_level'=>$v['level'],'with_rate'=>$v['rate']]);
                }
            }
        }
    }



    /**
     * 更新VIP会员等级
     */
    public function updateVipLevel($user_id){
        if($user_id<=0) return false;
        $ex = $this->equipOrderM->where('user_id',$user_id)->value('id');
        if(!$ex) return false;
        $user_data = $this->userM->getDetail($user_id,'level,vip_level');
        $push_act_count = $this->userM->alias('u')->join($this->shopOrderM->getTable().' p','u.id=p.user_id')->field('u.id')->where(['pid'=>$user_id])->group('user_id')->count();
        $push_count = $this->userM->field('u.id')->where(['pid'=>$user_id])->count();
        $arr = [
            1=>['effective'=>0,'con'=>0,'with_rate'=>50],
            2=>['effective'=>4,'con'=>200,'with_rate'=>35],
            3=>['effective'=>20,'con'=>1000,'with_rate'=>31],
            4=>['effective'=>40,'con'=>2000,'with_rate'=>28],
            5=>['effective'=>100,'con'=>5000,'with_rate'=>25],
        ];
        krsort($arr);
        foreach ($arr as $k => $v) {
            if($push_act_count>=$v['effective']&&$k>$user_data['vip_level']){
                return $this->userM->where('id',$user_id)->update(['vip_level'=>$k,'with_rate'=>$v['with_rate']]);
            }
        }
    }

    /**
     * 极差制度
     */
    public function gradation($list,$rate_arr){
        // echo "in gradation \n";
        //设置不同等级的利率   与领取的状态
        $name = 'rec';
        $max_level = 0;
        $arr = [];
        $count = count($rate_arr);
        foreach ($rate_arr as $key => $v) {
            if($max_level<$v['level']) $max_level = $v['level'];
            $arr[$v['level']] = $v['rate'];
            $cap = $name.$v['level'];
            $$cap = 0;
        }
        $new = [];
        $rate = 0;
        $key = 1;
        foreach ($list as $k => $v) {
            $cap = $name.$v['level'];
            if(!isset($$cap)) continue;
            //未领取
            if($$cap==0){
                //判断利率是否存在
                if(isset($rate_arr[$count-$key])){
                    //最大判断
                    $is_receive = $name.$rate_arr[$count-1]['level'];
                    if($$is_receive>0) continue;
                    //次级发放判断
                    if(($v['level']+1)>$max_level){
                        $is_receive = $name.$max_level;
                    }else{
                        $is_receive = $name.($v['level']+1);
                    }
                    if($$is_receive>0) continue;
                    $is_level_receive = $name.($v['level']-1);
                    if(isset($$is_level_receive)&&$$is_level_receive>0){
                        $rate = $arr[$v['level']]-$arr[$v['level']-1];
                    }else{
                        $rate = $arr[$v['level']]-$rate;
                    }
                    if(isset($v['user_id'])) $tmp['user_id'] = $v['user_id'];
                    else $tmp['user_id'] = $v['id'];
                    $tmp['rate'] = abs($rate);
                    $tmp['level'] = $v['level'];
                    $tmp['type'] = 1;
                    // echo "count:{$count} | key:{$key} | rate:{$rate} | user_id:{$tmp['user_id']} | level:{$v['level']} | rate:{$tmp['rate']}<br>";
                    $new[] = $tmp;
                    $$cap = 1;
                    $key++;
                    $last_level = $v['level']-1;
                    $ccap = $name.$last_level;
                    if(isset($$ccap)) $$ccap = 2;
                    continue;
                }else{
                    continue;
                }
            }
            //平级奖
            if($$cap==1){
                // continue;
                if(isset($v['user_id'])) $tmp['user_id'] = $v['user_id'];
                else $tmp['user_id'] = $v['id'];
                $tmp['level'] = $v['level'];
                $tmp['type'] = 2;
                $new[] = $tmp;
                $$cap = 2;
                continue;
            }
            //都领取过
            if($$cap>1){
                continue;
            }
        }
        // echo "end \n";
        return $new;
    }


    /**
     * 增加金额流水
     */
    public function addAmount($user_id,$amount,$coin_type,$type,$change_type,$remark,$to_user_id=0){
        return $this->poolM->updateRecord($user_id,$amount,$coin_type,$type,$change_type,$remark,$to_user_id);
    }

    /**
     * 增加金额和流水
     */
    public function addAmountRecord($user_id,$cny_amount,$amount,$rate,$coin_type,$type,$remark,$to_user_id=0){
        $data = $this->poolM->field('storage_basin,gratitude_pool,total_pool')->where('user_id',$user_id)->find();
        if($data['gratitude_pool']==0){
            return $this->failData('矿池数量为空');
        }
        if($coin_type==1){
            if($cny_amount>$data['gratitude_pool']){
                $cny_amount = $data['gratitude_pool'];
                $amount = bcdiv($cny_amount, $rate,2);
            }
        }else{
            $cny_amount = bcmul($amount, $rate,2);
            if($cny_amount>$data['gratitude_pool']){
                $cny_amount = $data['gratitude_pool'];
                $amount = bcdiv($cny_amount, $rate,2);
            }
        }
            
        $this->balanceM->startTrans();
        $data['storage_basin'] = bcadd($data['storage_basin'], $cny_amount,4);
        $data['gratitude_pool'] = bcsub($data['gratitude_pool'], $cny_amount,4);
        $res = $this->poolM->where('user_id',$user_id)->update($data);
        if(!$res){
            $this->balanceM->rollback();
            return $this->failData($remark.'增加失败');
        }
        $re_balance = $this->balanceM->updateBalance($user_id, $coin_type,$amount, true);
        if(!$re_balance){
            $this->balanceM->rollback();
            return $this->failData($remark.'增加失败');
        }
        $re_trading = $this->recordM->addRecord($user_id, $amount, $re_balance['before_amount'], $re_balance['amount'], $coin_type, $type, 1, $to_user_id, $remark);
        if(!$re_trading){
            $this->balanceM->rollback();
            return $this->failData($remark.'增加流水失败');
        }
        $this->balanceM->commit();
        return $this->successData();
    }

    /**
     * 返回错误信息。
     * @param type $message
     */
    protected function failData($message = null) {
        return array('success' => false, 'message' => $message);
    }

    /**
     * 返回成功信息
     * @param type $data
     */
    protected function successData($data = NULL) {
        return array('success' => true, 'data' => $data);
    }


    /**
     * 增加金额
     */
    public function updateAmountRecord($user_id,$amount,$coin_type,$type,$remark,$to_user_id=0){
        $this->balanceM->startTrans();
        $re_balance = $this->balanceM->updateBalance($user_id, $coin_type, $amount,1);
        if(!$re_balance){
            $this->balanceM->rollback();
            return false;
        }
        $userRecord = $this->recordM->addRecord($user_id, $amount, $re_balance['before_amount'], $re_balance['amount'], $coin_type, $type, 1, $to_user_id, $remark);
        if(!$userRecord){
            $this->balanceM->rollback();
            return false;
        }
        $this->balanceM->commit();
        return true;
    }
}